<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="unix,笔记," />










<meta name="description" content="Unix环境高级编程笔记-1最近开始读Unix环境高级编程，第一、二章就先不记了，从第三章开始。 函数open和openat12345#include &lt;fcntl.h&gt;int open(const char *path, int oflag, ... &#x2F;* mode_t mode *&#x2F;);int openat(int fd, const char* path, int oflag,">
<meta property="og:type" content="article">
<meta property="og:title" content="unix环境高级编程：非缓冲IO">
<meta property="og:url" content="http://liuyun000.gitee.io/2019/10/28/unix/unix%E7%8E%AF%E5%A2%83%E9%AB%98%E7%BA%A7%E7%BC%96%E7%A8%8B%EF%BC%9A%E9%9D%9E%E7%BC%93%E5%86%B2IO/index.html">
<meta property="og:site_name" content="liuyun的博客">
<meta property="og:description" content="Unix环境高级编程笔记-1最近开始读Unix环境高级编程，第一、二章就先不记了，从第三章开始。 函数open和openat12345#include &lt;fcntl.h&gt;int open(const char *path, int oflag, ... &#x2F;* mode_t mode *&#x2F;);int openat(int fd, const char* path, int oflag,">
<meta property="og:image" content="https://mzgmzg.github.io/images/unix_programing/fcnlt1.jpg">
<meta property="og:image" content="https://mzgmzg.github.io/images/unix_programing/fcntl2.jpg">
<meta property="article:published_time" content="2019-10-27T23:29:52.000Z">
<meta property="article:modified_time" content="2019-11-21T05:15:26.590Z">
<meta property="article:author" content="liuyun">
<meta property="article:tag" content="unix">
<meta property="article:tag" content="笔记">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://mzgmzg.github.io/images/unix_programing/fcnlt1.jpg">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://liuyun000.gitee.io/2019/10/28/unix/unix环境高级编程：非缓冲IO/"/>





  <title>unix环境高级编程：非缓冲IO | liuyun的博客</title>
  








<meta name="generator" content="Hexo 4.2.0"></head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">liuyun的博客</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/%20" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://liuyun000.gitee.io/2019/10/28/unix/unix%E7%8E%AF%E5%A2%83%E9%AB%98%E7%BA%A7%E7%BC%96%E7%A8%8B%EF%BC%9A%E9%9D%9E%E7%BC%93%E5%86%B2IO/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="liuyun">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="liuyun的博客">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">unix环境高级编程：非缓冲IO</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2019-10-28T07:29:52+08:00">
                2019-10-28
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/unix%E7%8E%AF%E5%A2%83%E9%AB%98%E7%BA%A7%E7%BC%96%E7%A8%8B/" itemprop="url" rel="index">
                    <span itemprop="name">unix环境高级编程</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <h2 id="Unix环境高级编程笔记-1"><a href="#Unix环境高级编程笔记-1" class="headerlink" title="Unix环境高级编程笔记-1"></a>Unix环境高级编程笔记-1</h2><p>最近开始读Unix环境高级编程，第一、二章就先不记了，从第三章开始。</p>
<h3 id="函数open和openat"><a href="#函数open和openat" class="headerlink" title="函数open和openat"></a>函数open和openat</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">open</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *path, <span class="keyword">int</span> oflag, ... <span class="comment">/* mode_t mode */</span>)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">openat</span><span class="params">(<span class="keyword">int</span> fd, <span class="keyword">const</span> <span class="keyword">char</span>* path, <span class="keyword">int</span> oflag, ... <span class="comment">/* mode_t mode */</span>)</span></span>;</span><br><span class="line"><span class="comment">/* 两函数返回值：若成功，返回文件描述符；若出错，返回-1。 */</span></span><br></pre></td></tr></table></figure>

<pre><code>我们将最后一个参数为..., ISO C 用这种方法表明余下的参数的数量及其类型是可变的，对于`open`函数而言，仅当创建新文件时才使用最后这个参数。在函数原型中将此参数防止在注释中。  

`path`参数时要打开或者创建文件的名字。`oflag`参数可用来说明此函数的多个选项。用下列一个或多个常量进行“或”运算构成`oflag`参数（这些常量在&lt;fcntl.h&gt;中定义）。</code></pre><ul>
<li>O_RDONLY          只读打开。</li>
<li>O_WRONLY         只写打开.</li>
<li>O_RDWR              读写打开。</li>
</ul>
<blockquote>
<p>  大多数实现将O_RDONLY定义为0，O_WRONLY定义为1，O_RDWR定义为2，以与早期程序兼容。</p>
</blockquote>
<ul>
<li>O_EXEC                只执行打开。</li>
<li>O_SEARCH          只搜索打开（应用于目录，基本上都不支持）</li>
</ul>
<p>以上五个常量中必须指定一个且只能指定一个，下列常量是可选的。</p>
<ul>
<li>O_APPEND          每次写时都追加到文件的尾端。</li>
<li>O_CLOEXEC         把FD_CLOEXEC常量设置为文件描述符标志。</li>
<li>O_CREAT               若文件不存在则创建它。使用此项时，<code>open</code>函数需勇士说明第三个参数<code>mode</code>。</li>
<li>O_DIRECTORY      如果<code>path</code>不是目录则出错。</li>
<li>O_EXCL                  如果同时制定了O_CREAT，而文件已经存在，则出错。这使得测试和创建文件成为原子操作。</li>
<li>O_NOCTTY            如果<code>path</code>引用的是终端设备，则不将该设备分配作为此进程的控制终端。</li>
<li>O_NOFOLLOW     如果<code>path</code>引用的是一个符号链接，则出错。</li>
<li>O_NONBLOCK      如果<code>path</code>引用的是一个FIFO、一个块特殊文件或一个字符特殊文件，此选项为文件的本次打开操作和后续的I/O操作设置非阻塞方式。</li>
<li>O_SYNC                 是每次<code>write</code>等待物理IO操作完成，包括由该<code>write</code>引起的文件属性更新所需的I/O。</li>
<li>O_TRUNC              如果此文件存在，而且为只写或读写成功打开，则将其长度截断为0.</li>
<li>O_TTY_INIT            如果打开一个还未打开的终端设备，设置非标准termios参数值，使其符合SUS。</li>
</ul>
<p>下面两个标志也是可选的。他们是SUS(以及POSIX.1)中同步输入和输出选项的一部分。</p>
<ul>
<li>O_DSYNC             每次<code>write</code>要等待物理I/O操作完成，但是如果该写操作并不影响读取刚写入的数据，则<strong>不需等待文件属性被更新</strong>。</li>
<li>O_RSYNC              使每一个以文件描述符作为参数进行的<code>read</code>操作等待，直至所有对文件用一部分挂起的写操作都完成。</li>
</ul>
<p>由<code>open</code>和<code>openat</code>函数返回的描述符一定是最小的未用描述符数值。  </p>
<p><code>fd</code>参数把<code>open</code>和<code>openat</code>函数分开，共有三种可能性。</p>
<ol>
<li><code>path</code>参数指定的使绝对路径，在这种情况下，<code>fd</code>参数被忽略掉。</li>
<li><code>path</code>参数指定的使相对路径名，<code>fd</code>参数指出了相对路径名在文件系统中的开始地址。<code>fd</code>参数是通过打开相对路径名所在的目录来获取。</li>
<li><code>path</code>参数制定了相对路径名，<code>fd</code>参数具有特殊值 AT_FDCWD。在这种情况下。路径名在当前工作目录中获取, <code>openat</code>函数在操作上与<code>open</code>类似。</li>
</ol>
<h3 id="函数creat"><a href="#函数creat" class="headerlink" title="函数creat"></a>函数creat</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">creat</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *path, <span class="keyword">mode_t</span> mode)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：若成功，返回只写打开的文件描述符；若出错，返回-1. */</span></span><br></pre></td></tr></table></figure>

<p>此函数等效于：</p>
<p><code>open(path, O_WRONLY|O_CREAT|O_TRUNC, mode);</code>  </p>
<h3 id="函数close"><a href="#函数close" class="headerlink" title="函数close"></a>函数close</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">close</span><span class="params">(<span class="keyword">int</span> fd)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：若成功，返回0；若出错，返回-1. */</span></span><br></pre></td></tr></table></figure>

<p>关闭一个文件是还会释放该进程加载该文件上的所有记录锁。  </p>
<p>当一个进程终止时，内核会自动关闭它所有打开文件。</p>
<h3 id="函数lseek"><a href="#函数lseek" class="headerlink" title="函数lseek"></a>函数lseek</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">off_t</span> <span class="title">lseek</span><span class="params">(<span class="keyword">int</span> fd, <span class="keyword">off_t</span> offset, <span class="keyword">int</span> whence)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：若成功，返回新的文件偏移量；若失败，返回为-1. */</span></span><br></pre></td></tr></table></figure>

<p>对参数<code>offset</code>的解释与参数<code>whence</code>有关.</p>
<ul>
<li><p>若<code>whence</code>是 SEEK_SET ，则将该文件的偏移量设置为据文件开始处offset个字节。</p>
</li>
<li><p>若<code>whence</code>是 SEEK_CUR，则将该文件的偏移量设置为当前值加offset，offset可谓正或负。</p>
</li>
<li><p>若<code>whence</code>是 SEEK_END，则将该文件的偏移量设置为文件长度加offset，offset可正可负。</p>
<pre><code> 通常，文件的当前偏移量应当是一个非负值，但是，某些设备可以能允许负的偏移量。但对于普通文件，其偏移量必须是非负值。因为偏移量可能是负值，所以在比较 `lseek` 的返回值时应当谨慎，不要测试它是否小于0，而要测试它是否等于-1.  

文件偏移量可以大于文件的当前长度，在这种情况下，对该文件的下一次写将加长该文件并在文件中构成一个空洞，这一点是允许的。位于文件中但没有写过的字节都被读为0.  </code></pre></li>
</ul>
<h3 id="函数read"><a href="#函数read" class="headerlink" title="函数read"></a>函数read</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">ssize_t</span> <span class="title">read</span><span class="params">(<span class="keyword">int</span> fd, <span class="keyword">void</span> *buf, <span class="keyword">size_t</span> nbytes)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：读到的字节数，若以到文件尾，返回0，若出错，返回-1. */</span></span><br></pre></td></tr></table></figure>



<h3 id="函数write"><a href="#函数write" class="headerlink" title="函数write"></a>函数write</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">ssize_t</span> <span class="title">write</span><span class="params">(<span class="keyword">int</span> fd, <span class="keyword">const</span> <span class="keyword">void</span> *buf, <span class="keyword">size_t</span> nbytes)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：若成功返回已写字节数；若出错，返回-1 */</span></span><br></pre></td></tr></table></figure>



<h3 id="原子操作"><a href="#原子操作" class="headerlink" title="原子操作"></a>原子操作</h3><h4 id="1-追加一个文件"><a href="#1-追加一个文件" class="headerlink" title="1. 追加一个文件"></a>1. 追加一个文件</h4><pre><code>不支持O_APPEND状态标志时，要追加，程序被携程下列格式：</code></pre><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">if</span> (lseek(fd, <span class="number">0L</span>, <span class="number">2</span>) &lt; <span class="number">0</span>)</span><br><span class="line">    	err_sys(<span class="string">"lseek error"</span>);</span><br><span class="line"><span class="keyword">if</span> (<span class="built_in">write</span>(fd, buf, <span class="number">100</span>) != <span class="number">100</span>)</span><br><span class="line">    	err_sys(<span class="string">"write error"</span>);</span><br></pre></td></tr></table></figure>

<pre><code>若两个`if`之间发生了进程切换且另一个进程对文件进行了添加，则此操作会将原来的字符覆盖。  </code></pre><h4 id="2-函数pread和pwrite"><a href="#2-函数pread和pwrite" class="headerlink" title="2. 函数pread和pwrite"></a>2. 函数pread和pwrite</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">ssize_t</span> <span class="title">pread</span><span class="params">(<span class="keyword">int</span> fd, <span class="keyword">void</span>* buf, <span class="keyword">size_t</span> nbytes, <span class="keyword">off_t</span> offset)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：读到的字节数，若已到文件尾，返回0；若出错，返回-1. */</span></span><br><span class="line"><span class="function"><span class="keyword">ssize_t</span> <span class="title">pwrite</span><span class="params">(<span class="keyword">int</span> fd, <span class="keyword">const</span> <span class="keyword">void</span> *buf, <span class="keyword">size_t</span> nbytes, <span class="keyword">off_t</span> offset)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：若成功，返回独到的字节数；若出错，返回-1. */</span></span><br></pre></td></tr></table></figure>

<pre><code>调用`pread`相当于调用`lseek`后调用`read`，但是`pread`又与这种顺序调用有下列重要区别。</code></pre><ul>
<li><p>调用<code>pread</code>时，无法中断其定位和读操作。</p>
</li>
<li><p>不更新当前文件偏移量。</p>
<p>  调用<code>pwrite</code>相当于调用<code>lseek</code>后调用<code>write</code>，但与他们有类似的区别。  </p>
</li>
</ul>
<h4 id="3-创建一个文件"><a href="#3-创建一个文件" class="headerlink" title="3. 创建一个文件"></a>3. 创建一个文件</h4><p><code>open</code>函数使用 O_CREAT 和 O_EXCL 状态描述符时检查文件是否存在和创建文件这两个操作时作为一个原子操作存在的。若没有这个原子操作，那么可能会编写下列程序：  </p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">if</span> ((fd = <span class="built_in">open</span>(pathname, O_WRONLY)) &lt; <span class="number">0</span>)</span><br><span class="line">    <span class="keyword">if</span> (errno == ENOENT)&#123;</span><br><span class="line">        <span class="keyword">if</span> ((fd = creat(path, mode)) &lt; <span class="number">0</span>)</span><br><span class="line">            err_sys(<span class="string">"creat error"</span>);</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        err_sys(<span class="string">"open error"</span>);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>



<h3 id="函数dup和dup2"><a href="#函数dup和dup2" class="headerlink" title="函数dup和dup2"></a>函数dup和dup2</h3><p>下面两个函数都可以用来复制一个现有的文件描述符。  </p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">dup</span><span class="params">(<span class="keyword">int</span> fd)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">dup2</span><span class="params">(<span class="keyword">int</span> fd, <span class="keyword">int</span> fd2)</span></span>;</span><br><span class="line"><span class="comment">/* 两函数返回值：若成功，返回新的文件描述符；若出错，返回-1. */</span></span><br></pre></td></tr></table></figure>

<p>由<code>dup</code>返回的新文件描述符一定是当前可用文件描述符的最小值。  </p>
<p>对于<code>dup2</code>可以用<code>fd2</code>参数指定新的描述符值。如果<code>fd2</code>已经打开，则先将其关闭。若<code>fd</code>等于<code>fd2</code>，则<code>dup2</code>返回<code>fd2</code>，而不关闭它。否则，<code>fd2</code>的FD_CLOEXEC文件描述符标志就被清楚，这样<code>fd2</code>在进程调用<code>exec</code>时是打开状态。  </p>
<h3 id="函数sync、fsync和fdatasync"><a href="#函数sync、fsync和fdatasync" class="headerlink" title="函数sync、fsync和fdatasync"></a>函数sync、fsync和fdatasync</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fsync</span><span class="params">(<span class="keyword">int</span> fd)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fdatasync</span><span class="params">(<span class="keyword">int</span> fd)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：若成功，返回0；若出错，返回-1. */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">sync</span><span class="params">(<span class="keyword">void</span>)</span></span>;</span><br></pre></td></tr></table></figure>

<p><code>sync</code>只是将所有修改过的快缓冲区排入写队列，然后就返回，它并不等待世界写磁盘操作结束。  </p>
<p><code>fsync</code>函数只对由文件描述符<code>fd</code>指定的一个文件起作用，并且等待写磁盘操作结束才返回。  </p>
<p><code>fdatasync</code>函数类似于<code>fsync</code>，但他只影响文件的数据部分。除数据外，<code>fsync</code>还会同步更新文件的属性。  </p>
<h3 id="函数fcntl"><a href="#函数fcntl" class="headerlink" title="函数fcntl"></a>函数fcntl</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fcntl</span><span class="params">(<span class="keyword">int</span> fd, <span class="keyword">int</span> cmd, ... <span class="comment">/* int arg */</span>)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：若成功，则依赖于cmd, 若出错，返回-1. */</span></span><br></pre></td></tr></table></figure>

<p><code>fcntl</code>函数共有以下5中功能。</p>
<ol>
<li>复制一个已有的描述符(<code>cmd</code>=F_DUPFD或F_DUPFD_CLOEXEC)。</li>
<li>获取/设置文件描述符标志(<code>cmd</code> = F_GETFD或F_SETFD)。</li>
<li>获取/设置文件状态标志(<code>cmd</code> = F_GETFL或F_GETFL)。</li>
<li>获取/设置异步I/O所有权（<code>cmd</code> = F_GETOWN或F_SETOWN）。</li>
<li>获取/设置记录锁(<code>cmd</code> = F_GETLK、F_SETLK或F_SETLKW)。</li>
</ol>
<p><img src="https://mzgmzg.github.io/images/unix_programing/fcnlt1.jpg" alt="fcntl1"></p>
<p><img src="https://mzgmzg.github.io/images/unix_programing/fcntl2.jpg" alt="fcntl2"></p>
<h3 id="函数ioctl"><a href="#函数ioctl" class="headerlink" title="函数ioctl"></a>函数ioctl</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt; /* System V */</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/ioctl.h&gt; /*BSD and Linux*/</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">ioctl</span><span class="params">(<span class="keyword">int</span> fd, <span class="keyword">int</span> request, ...)</span></span>;</span><br><span class="line"><span class="comment">/* 返回值：出错返回-1，否则其他值。 */</span></span><br></pre></td></tr></table></figure>




      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/unix/" rel="tag"># unix</a>
          
            <a href="/tags/%E7%AC%94%E8%AE%B0/" rel="tag"># 笔记</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2019/10/29/unix/unix%E7%8E%AF%E5%A2%83%E9%AB%98%E7%BA%A7%E7%BC%96%E7%A8%8B%EF%BC%9A%E6%96%87%E4%BB%B6%E5%92%8C%E7%9B%AE%E5%BD%95/" rel="prev" title="unix环境高级编程：文件和目录">
                unix环境高级编程：文件和目录 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">liuyun</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/%20%7C%7C%20archive">
              
                  <span class="site-state-item-count">16</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">9</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/tags/index.html">
                  <span class="site-state-item-count">21</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#Unix环境高级编程笔记-1"><span class="nav-number">1.</span> <span class="nav-text">Unix环境高级编程笔记-1</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#函数open和openat"><span class="nav-number">1.1.</span> <span class="nav-text">函数open和openat</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数creat"><span class="nav-number">1.2.</span> <span class="nav-text">函数creat</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数close"><span class="nav-number">1.3.</span> <span class="nav-text">函数close</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数lseek"><span class="nav-number">1.4.</span> <span class="nav-text">函数lseek</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数read"><span class="nav-number">1.5.</span> <span class="nav-text">函数read</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数write"><span class="nav-number">1.6.</span> <span class="nav-text">函数write</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#原子操作"><span class="nav-number">1.7.</span> <span class="nav-text">原子操作</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-追加一个文件"><span class="nav-number">1.7.1.</span> <span class="nav-text">1. 追加一个文件</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-函数pread和pwrite"><span class="nav-number">1.7.2.</span> <span class="nav-text">2. 函数pread和pwrite</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-创建一个文件"><span class="nav-number">1.7.3.</span> <span class="nav-text">3. 创建一个文件</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数dup和dup2"><span class="nav-number">1.8.</span> <span class="nav-text">函数dup和dup2</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数sync、fsync和fdatasync"><span class="nav-number">1.9.</span> <span class="nav-text">函数sync、fsync和fdatasync</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数fcntl"><span class="nav-number">1.10.</span> <span class="nav-text">函数fcntl</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数ioctl"><span class="nav-number">1.11.</span> <span class="nav-text">函数ioctl</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">liuyun</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Gemini</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginModelPath":"assets/","model":{"jsonPath":"/live2dw/assets/miku.model.json"},"display":{"position":"right","width":150,"height":300},"mobile":{"show":false},"log":false,"pluginJsPath":"lib/","pluginRootPath":"live2dw/","tagMode":false});</script></body>
</html>
